#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h> //提供close
#include <sys/types.h>//or socket types   定义数据类型
#include <sys/socket.h>
#include <netinet/in.h>
#include <thread>
using namespace std;
#define PORT 8080
#define BUFFER_SIZE 1024 //定义缓存区 之前不在这里写 在下面写
//char buffer [1024]={0}；
//下面写两个线程工作的函数
//发送和接受 handle_receive 和 handle_send，它们分别用于处理客户端的消息接收和发送。
//这两个函数通常在独立的线程中运行，以实现非阻塞的双向通信
void handle_receive(int client_sock) {
    char buffer[BUFFER_SIZE] = {0};
    while (true) {
        int num_bytes = read(client_sock, buffer, BUFFER_SIZE - 1);
        if (num_bytes <= 0) break; // 客户端断开连接或错误

        buffer[num_bytes] = '\0';
//上面调用 read 函数从 client_sock 套接字接收数据到 buffer 中。
//BUFFER_SIZE - 1 确保为字符串的空字符 \0 留出空间
//上次没有写这个‘\0‘ 按完enter没有后续了，没有结束点
        cout << "他说： " << buffer << endl;
    }
    close(client_sock);
}

void handle_send(int client_sock) {
    string message;//一个 string 类型的变量 message，用于存储要发送给客户端的消息。
    while (true) {
        cout << "向客户端发送消息: "<<endl;
        getline(cin, message);
//使用 send 函数将 message 发送到 client_sock 套接字
        if (send(client_sock, message.c_str(), message.size(), 0) < 0) {
            std::cerr << "Send error" << std::endl;
            break;
        }
    }
    close(client_sock);
}
// main 
int main() 
{
    //server_fd 用于存储服务器的套接字描述符
//new_socket 用于存储新客户端连接的套接字描述符
    int server_fd, new_socket;
    struct sockaddr_in address;//定义结构体存储地址
    socklen_t addrlen = sizeof(address);//定义socklen_t写入大小
//写一个socket ipv4 
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        return 1;
    }
//三件套 设为IPV4 然后IP设为任意 端口号为define过的PORT
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);
//bind 函数
    if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
        perror("bind failed");
        close(server_fd);
        return 1;
    }
//listen 函数
    if (listen(server_fd, 3) < 0) {
        perror("listen failed");
        close(server_fd);
        return 1;
    }
//accept 函数
    if ((new_socket = accept(server_fd, (struct sockaddr*)&address, &addrlen)) < 0) {
        perror("accept failed");
        close(server_fd);
        return 1;
    }
//双线程创建，分别分配任务
    std::thread receive_thread(handle_receive, new_socket);
    std::thread send_thread(handle_send, new_socket);
//join 阻塞
    receive_thread.join(); // 等待接收线程结束
    send_thread.join(); // 等待发送线程结束
//这里是避免了return0前面是join，前面写完报错 ai帮忙改正
//没完全懂 好像join后面写return 0 join不运行
    close(new_socket);
    close(server_fd);
    return 0;
}